package com.caidan.search.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.caidan.common.result.Result;
import com.caidan.common.result.ResultCodeEnum;
import com.caidan.model.domain.result.WebResult;
import com.caidan.search.config.ThreadPoolExecutorConfig;
import com.caidan.search.service.BingSearchService;
import com.caidan.search.spider.BingSearchSpider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BingSearchServiceImpl implements BingSearchService {

    private static final int NON_MEMBER_MAX_PAGE = 3;
    private static final int MEMBER_MAX_PAGE = 5;

    @Autowired
    private ThreadPoolExecutor memberThreadPool; // 会员线程池
    @Autowired
    private ThreadPoolExecutor userThreadPool;   // 普通用户线程池
    @Autowired
    private ThreadPoolExecutorConfig threadPoolExecutorConfig; // 线程池配置类

    @Override
    public Result bingSearch(Long userId, boolean isMember, String param) {
        Map<String, Object> resType = new HashMap<>();
        BingSearchSpider bingSearchSpider = new BingSearchSpider();
        CopyOnWriteArrayList<WebResult> copyOnWriteArrayList = new CopyOnWriteArrayList<>();

        // 计算最大请求页数
        int maxPage = isMember ? MEMBER_MAX_PAGE : NON_MEMBER_MAX_PAGE;

        // 使用 CountDownLatch 确保所有任务执行完毕后再返回结果
        CountDownLatch latch = new CountDownLatch(maxPage);

        for (int i = 0; i < maxPage; i++) {
            final Integer tmp = i;
            try {
                submitTask(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Map<String, Object> stringObjectMap = bingSearchSpider.searchBing(param, tmp * 10);
                            if (ObjectUtil.isEmpty(stringObjectMap)) {
                                throw new RuntimeException("Search result is empty");
                            }

                            // 处理第一页特有的"smart"字段
                            if (tmp == 0) {
                                String smart = (String) stringObjectMap.get("smart");
                                if (!StrUtil.isBlank(smart)) {
                                    resType.put("smart", smart);
                                }
                            }

                            // 获取搜索结果并添加到列表
                            List<WebResult> searchResults = (List<WebResult>) stringObjectMap.get("res");

                            if (ObjectUtil.isEmpty(searchResults)) {
                                throw new RuntimeException("Search results are empty");
                            }
                            copyOnWriteArrayList.addAll(searchResults);
                        } catch (Exception e) {
                            log.error("[bingSearch Service] Error during search: ", e);
                        } finally {
                            // 无论任务成功与否，计数器减1
                            latch.countDown();
                        }
                    }
                }, isMember);
            } catch (Exception e) {
                log.error("[bingSearch Service] Search error for userId {} and param {}", userId, param, e);
                return Result.fail(ResultCodeEnum.SERVICE_ERROR.getMessage());
            }
        }
        // 等待所有任务完成
        try {
            latch.await();  // 等待所有异步任务执行完毕
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("Thread interrupted while waiting for tasks to complete", e);
            return Result.fail(ResultCodeEnum.SERVICE_ERROR.getMessage());
        }
//        // 任务完成后返回结果
//        List<WebResult> uniqueList = copyOnWriteArrayList.stream()
//                // 先根据 title 去重
//                .collect(Collectors.toMap(WebResult::getTitle, obj -> obj, (existing, replacement) -> existing))
//                .values().stream()
//                // 过滤掉没有图片的项，并按照图片有无排序：有图片的排前面
//                .filter(result -> result.getImgUrl() != null && !result.getImgUrl().isEmpty())
//                .sorted(Comparator.comparing(WebResult::getDescription, Comparator.comparingInt(String::length)))
//                // 按照描述的长度升序排序
//                .collect(Collectors.toList());
        resType.put("res", copyOnWriteArrayList);
        return Result.ok(resType);
    }
    // 提交任务方法
    public void submitTask(Runnable task, boolean isMember) {
        if (isMember) {
            // 会员任务直接提交到会员线程池
            memberThreadPool.execute(task);
        } else {
            // 普通用户任务提交到普通用户线程池
            if (userThreadPool.getQueue().size() < 100) {
                // 如果普通用户任务队列较少，则提交到普通用户线程池
                userThreadPool.execute(task);
            } else {
                // 如果普通用户任务队列较多，则提交到会员线程池
                memberThreadPool.execute(task);
            }
        }
    }
}
